<template>
  <div class="app-container">
    <el-card class="filter-container" shadow="never">
      <div>
        <i class="el-icon-search"></i>
        <span>筛选搜索</span>
        <el-button
            size="small"
            style="float:right"
            type="primary"
            @click="handleSearchList()">
          查询搜索
        </el-button>
        <el-button
            size="small"
            style="float:right;margin-right: 15px"
            @click="handleResetSearch()">
          重置
        </el-button>
      </div>
      <div style="margin-top: 15px">
        <el-form v-model="listQuery" :inline="true" label-width="auto" size="small">
          <el-form-item label="项目：">
            <el-select v-model="listQuery.projectId" clearable
                       @change="projectChangeThenInitDatasourceOption();handleSearchList()"
                       @input="forceUpdateElement">
              <el-option
                  v-for="item in allProjectOption"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="数据源：">
            <el-select v-model="listQuery.datasourceId" clearable filterable no-data-text="请先选择项目" style="width:100%"
                       @change="handleSearchList">
              <el-option
                  v-for="item in datasourceOption"
                  :key="item.id"
                  :label="item.remark"
                  :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="表名：">
            <el-input v-model="listQuery.tableName" class="input-width" clearable placeholder=""
                      @input="forceUpdateElement"></el-input>
          </el-form-item>
          <el-form-item label="字段：">
            <el-input v-model="listQuery.filedName" class="input-width" clearable placeholder=""
                      @input=forceUpdateElement></el-input>
          </el-form-item>
        </el-form>
      </div>
    </el-card>

    <el-card class="operate-container" shadow="never">
      <i class="el-icon-tickets"></i>
      <span>数据列表</span>
      <el-button v-loading="listLoading" class="btn-add" size="mini" style="margin-left: 20px" type="warning"
                 @click="handleAdd()">添加
      </el-button>
    </el-card>

    <div class="table-container">
      <el-table ref="roleTable"
                v-loading="listLoading"
                :data="list"
                border style="width: 100%;">
        <el-table-column type="expand">
          <template slot-scope="props">
            <el-form class="demo-table-expand" inline label-position="left"
                     style="background-color: #eeeeee4f">
              <el-form-item label="tag颜色">
                <span>{{ props.row.showTagColor }}</span>
              </el-form-item>
              <el-form-item label="选项值">
                <span>{{ props.row.showSelectOption }}</span>
              </el-form-item>
            </el-form>
          </template>
        </el-table-column>
        <el-table-column align="center" label="项目">
          <template slot-scope="scope">
            {{ (idToAllProjectJson[(scope.row.projectId)] || {}).name }}
          </template>
        </el-table-column>
        <el-table-column align="center" label="数据源" prop="">
          <template slot-scope="scope">
            {{ (scope.row.projectDatasource || {}).remark }}
          </template>
        </el-table-column>
        <el-table-column align="center" label="表名" prop="tableName"/>
        <el-table-column align="center" label="字段" prop="filedName"/>
        <el-table-column align="center" label="显示名称" prop="showName"/>
        <el-table-column align="center" label="类型" prop="showType">
          <template slot-scope="scope">
            <el-tag type="primary">{{ scope.row.showType }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column align="center" label="列表收起" prop="showInExpand" width="80">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.showInExpand == '0'" type="danger">否</el-tag>
            <el-tag v-if="scope.row.showInExpand == '1'" type="primary">是</el-tag>
          </template>
        </el-table-column>
        <el-table-column align="center" label="必填" prop="showRequire" width="80">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.showRequire == '0'" type="danger">否</el-tag>
            <el-tag v-if="scope.row.showRequire == '1'" type="primary">是</el-tag>
          </template>
        </el-table-column>
        <el-table-column align="center" label="tag形式" prop="showAsTag" width="100">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.showAsTag == '0'" type="danger">否</el-tag>
            <el-tag v-else-if="scope.row.showAsTag == '1'" type="primary">是</el-tag>
            <span v-else >-</span>
          </template>
        </el-table-column>

        <el-table-column align="center" label="操作" width="250">
          <template slot-scope="scope">
            <el-button v-loading="listLoading" size="mini"
                       type="primary"
                       @click="handleUpdate(scope.row)">
              编辑
            </el-button>
            <el-button size="mini"
                       type="danger"
                       @click="handleDelete(scope.row)">删除
            </el-button>
            <el-button size="mini"
                       v-loading="listLoading" type="success"
                       @click="handleAddByCopy(scope.row)">复制
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="pagination-container">
      <el-pagination
          :current-page.sync="listQuery.current"
          :page-size="listQuery.pageSize"
          :page-sizes="[5,10,15]"
          :total="total"
          background
          layout="total, sizes,prev, pager, next,jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    <el-dialog v-loading="listLoading" :visible.sync="editDialogVisible"
               title="编辑项目表字段映射配置"
               width="60%">
      <el-form ref="roleForm"
               :model="projectTableFiledConfig"
               label-width="auto" size="small">
        <el-form-item label="项目：">
          <el-select v-model="projectTableFiledConfig.projectId" filterable style="width:100%"
                     @change="selectProjectChange">
            <el-option
                v-for="item in allProjectOption"
                :key="item.id"
                :label="item.name"
                :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="数据源：" prop="datasourceId">
          <el-select v-model="projectTableFiledConfig.datasourceId" clearable filterable style="width:100%">
            <el-option
                v-for="item in datasourceOption"
                :key="item.id"
                :label="item.remark"
                :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="表名：">
          <el-select v-model="projectTableFiledConfig.tableName" filterable style="width:100%"
                     @change="selectTableNameChange">
            <el-option
                v-for="item in projectTableOption"
                :key="item.value"
                :label="item.label"
                :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="字段：">
          <el-select v-model="projectTableFiledConfig.filedName" filterable style="width:100%"
                     @change="handleFiledNameUpdate">
            <el-option
                v-for="item in projectTableFieldOption[projectTableFiledConfig.tableName]"
                :key="item.value"
                :label="item.label"
                :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="显示名称：">
          <el-input v-model="projectTableFiledConfig.showName" @input="forceUpdateElement"></el-input>
        </el-form-item>
        <el-form-item label="类型：">
          <el-select v-model="projectTableFiledConfig.showType" style="width:100%" @change="onShowTypeChange">
            <el-option v-for="item in fieldTypeSelectOption"
                       :key="item.value"
                       :disabled="item.disabled"
                       :label="item.label"
                       :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>

        <template v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType]">
          <template
              v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType].fieldType == 'option'">
            <el-form-item label="从字典中选择：">
              <el-button size="mini" style="margin-left: 10px" type="primary"
                         @click="showComponent()">从字典中选择选项值
              </el-button>
            </el-form-item>
            <el-form-item label="tag形式：">
              <el-radio-group v-model="projectTableFiledConfig.showAsTag">
                <el-radio label="0">否</el-radio>
                <el-radio label="1">是</el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="选项值：">
              <div style="text-align: center;width: 60%">
                <div style="display: flex">
                  <div style="flex: 1">数据值</div>
                  <div style="flex: 1;margin-left: 10px">显示名称</div>
                  <div v-if="projectTableFiledConfig.showAsTag == '1'" style="flex: 1;margin-left: 10px">
                    tag颜色
                  </div>
                  <div v-if="projectTableFiledConfig.showAsTag == '1'" style="flex: 1;margin-left: 10px">
                    颜色预览
                  </div>
                  <div style="flex: 1">
                    <el-button icon="el-icon-plus" size="mini" type="primary"
                               @click="addShowSelectOptionEdit">添加
                    </el-button>
                  </div>
                </div>
                <div v-for="item in showSelectOptionEdit" style="display: flex">
                  <el-input v-model="item.value" size="mini" style="flex: 1"></el-input>
                  <el-input v-model="item.label" size="mini" style="flex: 1;margin-left: 10px"></el-input>

                  <el-select v-if="projectTableFiledConfig.showAsTag == '1'" v-model="item.color" size="mini"
                             style="flex: 1;margin-left: 10px">
                    <el-option label="蓝色" value="primary"></el-option>
                    <el-option label="红色" value="danger"></el-option>
                    <el-option label="绿色" value="success"></el-option>
                    <el-option label="橙色" value="warning"></el-option>
                    <el-option label="灰色" value="info"></el-option>
                  </el-select>

                  <el-tag v-if="projectTableFiledConfig.showAsTag == '1'" :type="item.color"
                          style="flex: 1;margin-left: 10px">{{ item.label }}
                  </el-tag>

                  <div style="flex: 1;">
                    <el-button icon="el-icon-minus" size="mini" type="danger"
                               @click="deleteShowSelectOptionEdit(item)">删除
                    </el-button>
                  </div>
                </div>
              </div>
            </el-form-item>
          </template>

          <template
              v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType].fieldType == 'collection'">
            <el-form-item label="关联表字段：">
              <div style="color: red">tips: 哪个表的哪个字段与此表的 {{ projectTableFiledConfig.filedName }} 字段关联
              </div>
              <el-cascader v-model="collectionTableFieldValue" :options="associationTableField"
                           filterable
                           placeholder="请选择关联表字段"
                           style="width: 100%;"></el-cascader>
            </el-form-item>
            <el-form-item label="显示方式：">
              <el-select v-model="collectionShowTypeValue" style="width:100%">
                <el-option label="弹窗形式" value="vue"></el-option>
                <el-option label="只查询数据（无分页，不适合数据多的场景）" value="data"></el-option>
              </el-select>
            </el-form-item>
          </template>

          <template
              v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType].fieldType == 'association'">
            <el-form-item label="关联表字段：">
              <div style="color: red">tips: 哪个表的哪个字段与此表关联</div>
              <el-cascader v-model="associationTableFieldValue" :options="associationTableField"
                           filterable
                           placeholder="请选择关联表字段"
                           style="width: 100%;"></el-cascader>
            </el-form-item>
            <el-form-item label="显示关联表字段：">
              <div style="color: red">tips: 展示时，取关联表的哪个字段</div>
              <el-select v-model="associationTableShowField" clearable style="width:100%">
                <el-option
                    v-for="item in projectTableFieldOption[associationTableFieldValue[0]]"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
          </template>

          <template
              v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType].fieldType == 'switch'">

            <el-form-item label="开关switch配置：">
              <div style="text-align: center;width: 100%">
                <div style="display: flex">
                  <div style="flex: 1">状态</div>
                  <div style="flex: 1">数据值</div>
                  <div style="flex: 1;margin-left: 10px">显示名称</div>
                  <div style="flex: 1;margin-left: 10px">
                    开关颜色
                  </div>
                  <div style="flex: 1;margin-left: 10px">
                    预览
                  </div>
                </div>
                <div v-for="(item,index) in showSelectOptionEdit" style="display: flex">
                  <div style="flex: 1">{{ index === 0 ? '关闭' : '打开' }}</div>
                  <el-input v-model="item.value" size="mini" style="flex: 1"></el-input>
                  <el-input v-model="item.label" size="mini" style="flex: 1;margin-left: 10px"></el-input>

                  <el-select v-model="item.color" allow-create clearable filterable size="mini"
                             style="flex: 1;margin-left: 10px" @change="switchRefreshFun">
                    <el-option label="蓝色" value="#409eff"></el-option>
                    <el-option label="红色" value="#F56C6C"></el-option>
                    <el-option label="绿色" value="#13ce66"></el-option>
                    <el-option label="橙色" value="#E6A23C"></el-option>
                    <el-option label="灰色" value="#909399"></el-option>
                  </el-select>

                  <div v-if="switchRefresh" style="flex: 1;margin-left: 10px;text-align: center">
                    <el-switch v-model="item.value"
                               :active-color="showSelectOptionEdit[1].color?showSelectOptionEdit[1].color:''"
                               :active-text="showSelectOptionEdit[1].label"
                               :active-value="showSelectOptionEdit[1].value"
                               :inactive-color="showSelectOptionEdit[0].color?showSelectOptionEdit[0].color:''"
                               :inactive-text="showSelectOptionEdit[0].label"
                               :inactive-value="showSelectOptionEdit[0].value"
                               disabled
                    ></el-switch>
                  </div>
                </div>
              </div>
            </el-form-item>
          </template>
        </template>
        <el-form-item label="在expand中显示：">
          <el-radio-group v-model="projectTableFiledConfig.showInExpand">
            <el-radio label="0">否</el-radio>
            <el-radio label="1">是</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="必填：">
          <el-radio-group v-model="projectTableFiledConfig.showRequire">
            <el-radio label="0">否</el-radio>
            <el-radio label="1">是</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" @click="editDialogVisible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="handleEditDialogConfirm()">确 定</el-button>
      </span>
    </el-dialog>


    <el-dialog v-loading="listLoading" :visible.sync="addDialogVisible"
               title="新增项目表字段映射配置"
               width="60%">
      <el-form ref="roleForm"
               :model="projectTableFiledConfig"
               label-width="auto" size="small">
        <el-form-item label="项目：">
          <el-select v-model="projectTableFiledConfig.projectId" filterable style="width:100%"
                     @change="selectProjectChange">
            <el-option
                v-for="item in allProjectOption"
                :key="item.id"
                :label="item.name"
                :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="数据源：" prop="datasourceId">
          <el-select v-model="projectTableFiledConfig.datasourceId" clearable filterable style="width:100%"
                     @change="selectProjectChange">
            <el-option
                v-for="item in datasourceOption"
                :key="item.id"
                :label="item.remark"
                :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="表名：">
          <el-select v-model="projectTableFiledConfig.tableName" filterable style="width:100%"
                     @change="selectTableNameChange">
            <el-option
                v-for="item in projectTableOption"
                :key="item.value"
                :label="item.label"
                :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="字段：">
          <el-select v-model="projectTableFiledConfig.filedName" filterable style="width:100%"
                     @change="handleFiledNameUpdate">
            <el-option
                v-for="item in projectTableFieldOption[projectTableFiledConfig.tableName]"
                :key="item.value"
                :label="item.label"
                :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="显示名称：">
          <el-input v-model="projectTableFiledConfig.showName" @input="forceUpdateElement"></el-input>
        </el-form-item>
        <el-form-item label="类型：">
          <el-select filterable v-model="projectTableFiledConfig.showType" style="width:100%" @change="onShowTypeChange">
            <el-option v-for="item in fieldTypeSelectOption"
                       :key="item.value"
                       :disabled="item.disabled"
                       :label="item.label"
                       :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>

        <template v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType]">
          <template
              v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType].fieldType == 'option'">
            <el-form-item label="从字典中选择：">
              <el-button size="mini" style="margin-left: 10px" type="primary"
                         @click="showComponent()">从字典中选择选项值
              </el-button>
            </el-form-item>
            <el-form-item label="tag形式：">
              <el-radio-group v-model="projectTableFiledConfig.showAsTag">
                <el-radio label="0">否</el-radio>
                <el-radio label="1">是</el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="选项值：">
              <div style="text-align: center;width: 60%">
                <div style="display: flex">
                  <div style="flex: 1">数据值</div>
                  <div style="flex: 1;margin-left: 10px">显示名称</div>
                  <div v-if="projectTableFiledConfig.showAsTag == '1'" style="flex: 1;margin-left: 10px">
                    tag颜色
                  </div>
                  <div v-if="projectTableFiledConfig.showAsTag == '1'" style="flex: 1;margin-left: 10px">
                    颜色预览
                  </div>
                  <div style="flex: 1">
                    <el-button icon="el-icon-plus" size="mini" type="primary"
                               @click="addShowSelectOptionEdit">添加
                    </el-button>
                  </div>
                </div>
                <div v-for="item in showSelectOptionEdit" style="display: flex">
                  <el-input v-model="item.value" size="mini" style="flex: 1"></el-input>
                  <el-input v-model="item.label" size="mini" style="flex: 1;margin-left: 10px"></el-input>

                  <el-select v-if="projectTableFiledConfig.showAsTag == '1'" v-model="item.color" size="mini"
                             style="flex: 1;margin-left: 10px">
                    <el-option label="蓝色" value="primary"></el-option>
                    <el-option label="红色" value="danger"></el-option>
                    <el-option label="绿色" value="success"></el-option>
                    <el-option label="橙色" value="warning"></el-option>
                    <el-option label="灰色" value="info"></el-option>
                  </el-select>

                  <el-tag v-if="projectTableFiledConfig.showAsTag == '1'" :type="item.color"
                          style="flex: 1;margin-left: 10px">{{ item.label }}
                  </el-tag>

                  <div style="flex: 1;">
                    <el-button icon="el-icon-minus" size="mini" type="danger"
                               @click="deleteShowSelectOptionEdit(item)">删除
                    </el-button>
                  </div>
                </div>
              </div>
            </el-form-item>
          </template>

          <template
              v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType].fieldType == 'collection'">

            <el-form-item label="关联表字段：">
              <div style="color: red">tips: 哪个表的哪个字段与此表的 {{ projectTableFiledConfig.filedName }} 字段关联
              </div>
              <el-cascader v-model="collectionTableFieldValue" :options="associationTableField"
                           filterable
                           placeholder="请选择关联表字段"
                           style="width: 100%;"></el-cascader>
            </el-form-item>

            <el-form-item label="显示方式：">
              <el-select v-model="collectionShowTypeValue" style="width:100%">
                <el-option label="弹窗形式" value="vue"></el-option>
                <el-option label="只查询数据（无分页，不适合数据多的场景）" value="data"></el-option>
              </el-select>
            </el-form-item>
          </template>

          <template
              v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType].fieldType == 'association'">
            <el-form-item label="关联表字段：">
              <div style="color: red">tips: 哪个表的哪个字段与此表关联</div>
              <el-cascader v-model="associationTableFieldValue" :options="associationTableField"
                           filterable
                           placeholder="请选择关联表字段"
                           style="width: 100%;"></el-cascader>
            </el-form-item>

            <el-form-item label="显示关联表字段：">
              <div style="color: red">tips: 展示时，取关联表的哪个字段</div>
              <el-select v-model="associationTableShowField" clearable style="width:100%">
                <el-option
                    v-for="item in projectTableFieldOption[associationTableFieldValue[0]]"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
          </template>

          <template
              v-if="templateFieldTypeToTemplateFieldConfigOption[projectTableFiledConfig.showType].fieldType == 'switch'">
            <el-form-item label="开关switch配置：">
              <div style="text-align: center;width: 100%">
                <div style="display: flex">
                  <div style="flex: 1">状态</div>
                  <div style="flex: 1">数据值</div>
                  <div style="flex: 1;margin-left: 10px">显示名称</div>
                  <div style="flex: 1;margin-left: 10px">
                    开关颜色
                  </div>
                  <div style="flex: 1;margin-left: 10px">
                    预览
                  </div>
                </div>
                <div v-for="(item,index) in showSelectOptionEdit" style="display: flex">
                  <div style="flex: 1">{{ index === 0 ? '关闭' : '打开' }}</div>
                  <el-input v-model="item.value" size="mini" style="flex: 1"></el-input>
                  <el-input v-model="item.label" size="mini" style="flex: 1;margin-left: 10px"></el-input>

                  <el-select v-model="item.color" allow-create clearable filterable size="mini"
                             style="flex: 1;margin-left: 10px" @change="switchRefreshFun">
                    <el-option label="蓝色" value="#409eff"></el-option>
                    <el-option label="红色" value="#F56C6C"></el-option>
                    <el-option label="绿色" value="#13ce66"></el-option>
                    <el-option label="橙色" value="#E6A23C"></el-option>
                    <el-option label="灰色" value="#909399"></el-option>
                  </el-select>

                  <div v-if="switchRefresh" style="flex: 1;margin-left: 10px;text-align: center">
                    <el-switch v-model="item.value"
                               :active-color="showSelectOptionEdit[1].color?showSelectOptionEdit[1].color:''"
                               :active-text="showSelectOptionEdit[1].label"
                               :active-value="showSelectOptionEdit[1].value"
                               :inactive-color="showSelectOptionEdit[0].color?showSelectOptionEdit[0].color:''"
                               :inactive-text="showSelectOptionEdit[0].label"
                               :inactive-value="showSelectOptionEdit[0].value"
                               disabled
                    ></el-switch>
                  </div>
                </div>
              </div>
            </el-form-item>
          </template>
        </template>
        <el-form-item label="在expand中显示：">
          <el-radio-group v-model="projectTableFiledConfig.showInExpand">
            <el-radio label="0">否</el-radio>
            <el-radio label="1">是</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="必填：">
          <el-radio-group v-model="projectTableFiledConfig.showRequire">
            <el-radio label="0">否</el-radio>
            <el-radio label="1">是</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" @click="addDialogVisible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="handleAddDialogConfirm()">确 定</el-button>
      </span>
    </el-dialog>

    <projectTableFiledConfigPre-component :visible="projectTableFiledConfigPreSelectVisible"
                                          @close="projectTableFiledConfigPreSelectVisible =false"
                                          @onSelect="onComponentSelect"></projectTableFiledConfigPre-component>
  </div>
</template>
<script>
import ProjectTableFiledConfigPreComponent from "@/views/projectTableFiledConfigPre/component";
import {projectTableFiledConfigPostRequire} from '@/api/projectTableFiledConfig'
import {projectPostRequire} from '@/api/project'
import {tablePostRequire} from '@/api/tableConfig'
import {templateFieldConfigPostRequire} from "@/api/templateFieldConfig";
import {Message} from "element-ui";

const defaultListQuery = {
  current: 1,
  pageSize: 10,
  projectId: undefined,
  datasourceId: undefined,
  tableName: undefined,
  filedName: undefined,
}
const defaultProjectTableFiledConfig = {
  id: undefined,
  projectId: undefined,
  datasourceId: undefined,
  tableName: undefined,
  filedName: undefined,
  javaType: undefined,
  showName: undefined,
  showType: 'text',
  showInExpand: '0',
  showRequire: '0',
  showAsTag: '0',
  showTagColor: undefined,
  showSelectOption: undefined,
  associationTable: undefined,
  collectionTable: undefined,
}

const defaultFieldTypeSelect = [
  {label: "text-文本", value: "text"},
  {label: "textarea-文本域", value: "textarea"},
  {label: "number-数值", value: "number"},
  {label: "radio-单选", value: "radio"},
  {label: "checkbox-多选", value: "checkbox"},
  {label: "date-日期", value: "date"},
  {label: "dateTime-时间", value: "dateTime"},
  {label: "img-图片", value: "img", allowType: 'int'},
  {label: "file-文件", value: "file"},
  {label: "rate-评分", value: "rate"},
  {label: "association-外键一对一", value: "association"},
  {label: "collection-一对多", value: "collection"},
]
const defaultTemplateFieldTypeToTemplateFieldConfigOption = {
  "radio": {"fieldType": "option"},
  "checkbox": {"fieldType": "option"},
  "association": {"fieldType": "association"},
  "collection": {"fieldType": "collection"},
  "switch": {"fieldType": "switch"},
}
export default {
  components: {ProjectTableFiledConfigPreComponent},
  name: 'projectTableFiledConfigList',
  data() {
    return {
      datasourceOption: [],
      projectTableFieldOption: {},
      projectTableOption: [],
      allProjectOption: [],
      idToAllProjectJson: {},
      switchRefresh: true,
      fieldTypeSelectOption: [],

      projectTableFiledConfigPreSelectVisible: false,


      listQuery: this.$deepClone(defaultListQuery),
      list: null,
      total: null,
      listLoading: false,
      addDialogVisible: false,
      editDialogVisible: false,
      projectTableFiledConfig: this.$deepClone(defaultProjectTableFiledConfig),

      fromCopy: false,
      showSelectOptionEdit: [],

      associationTableField: [],
      collectionTableFieldValue: [],
      collectionShowTypeValue: 'vue',
      associationTableFieldValue: [],
      associationTableShowField: '',
      fromTablePage: false,

      //模板名称->模板字段配置
      templateFieldTypeToTemplateFieldConfigOption: defaultTemplateFieldTypeToTemplateFieldConfigOption,
      templateFieldConfigOption: [],
    }
  },
  created() {
    if (this.$route.query) {
      let keys = Object.keys(this.$route.query)
      if (keys.length > 0) {
        keys.forEach(k => {
          let v = this.$route.query[k]
          if (k == 'projectId' || k == 'datasourceId') {
            v = parseInt(v)
          }
          this.listQuery[k] = v
        })
        this.fromTablePage = true
      }
    }

    let currentProject = JSON.parse((localStorage.getItem('currentProject') || "{}"))
    if (currentProject && !this.listQuery.projectId) {
      this.listQuery.projectId = currentProject.id;
    }
    this.listLoading = true
    this.getAllProject(() => {
      this.getList()
      this.projectChangeThenInitDatasourceOption()
    })
  },
  methods: {
    getAllProject(resolveFn) {
      this.listLoading = true;
      projectPostRequire("getAllProjectOption").then(response => {
        this.allProjectOption = response.data || [];
        if (this.allProjectOption.length > 0) {
          this.allProjectOption.forEach(item => {
            this.idToAllProjectJson[item.id] = item;
          })
        }
      }).finally(() => {
        this.listLoading = false;
        if (resolveFn) {
          resolveFn()
        }
      })
    },
    switchRefreshFun() {
      this.switchRefresh = true;
      this.switchRefresh = false;
      this.$nextTick(() => {
        this.switchRefresh = true;
      })
    },
    getTemplateName() {
      if (this.projectTableFiledConfig.projectId) {
        return this.idToAllProjectJson[this.projectTableFiledConfig.projectId].template
      }
      return ''
    },
    genFieldTypeSelectLimit() {
      this.fieldTypeSelectOption = []
      let javaType = this.projectTableFiledConfig.javaType;
      if (javaType) {
        if (javaType.indexOf("(") != -1) {
          javaType = javaType.substring(0, javaType.indexOf("("))
        }
        if (javaType.indexOf(".") != -1) {
          javaType = javaType.substring(javaType.lastIndexOf(".") + 1)
        }
        var templateName = this.getTemplateName();
        let gotoDefaultSelectOption = false
        let temp = []
        if (templateName) {
          var templateFieldConfigOptionElement = this.templateFieldConfigOption;
          if (!templateFieldConfigOptionElement || templateFieldConfigOptionElement.length <= 0) {
            gotoDefaultSelectOption = true;
          } else {
            //后台配置
            templateFieldConfigOptionElement.forEach(tfc => {
              let banType = tfc.banFieldType;
              let allowType = tfc.allowFieldType;
              let disabled = false;
              if (banType && banType.indexOf(javaType) >= 0) {
                disabled = true
              } else if (allowType && allowType.indexOf(javaType) < 0) {
                disabled = true
              }
              temp.push({
                label: tfc.componentName + '-' + tfc.componentLabel,
                value: tfc.componentName,
                disabled: disabled
              })
            })
          }
        }
        if (!templateName || gotoDefaultSelectOption) {
          //默认配置
          defaultFieldTypeSelect.forEach(ds => {
            let banType = ds.banType;
            let allowType = ds.allowType;
            let disabled = false;
            if (banType && banType.indexOf(javaType) >= 0) {
              disabled = true
            } else if (allowType && allowType.indexOf(javaType) < 0) {
              disabled = true
            }
            temp.push({...ds, disabled: disabled})
          })
        }
        temp.sort((a, b) => {
          if (a.disabled && !b.disabled) {
            return 1; // a 排在 b 后面
          }
          if (!a.disabled && b.disabled) {
            return -1; // a 排在 b 前面
          }
          return 0; // 保持原有顺序
        });
        this.fieldTypeSelectOption = temp
      }
    },
    selectTemplateChange(projectId, resolveFn) {
      let that = this
      that.templateFieldTypeToTemplateFieldConfigOption = defaultTemplateFieldTypeToTemplateFieldConfigOption
      if (projectId) {
        that.templateFieldConfigOption = []
        templateFieldConfigPostRequire('getByProjectId', {projectId: projectId})
            .then(response => {
              let templateFieldConfigOptionTemp = response.data || []
              that.templateFieldConfigOption = templateFieldConfigOptionTemp
              that.templateFieldTypeToTemplateFieldConfigOption = {}
              if (templateFieldConfigOptionTemp && templateFieldConfigOptionTemp.length > 0) {
                for (let i = 0; i < templateFieldConfigOptionTemp.length; i++) {
                  const templateFieldConfigOptionElement = templateFieldConfigOptionTemp[i];
                  that.templateFieldTypeToTemplateFieldConfigOption[templateFieldConfigOptionElement.componentName] = templateFieldConfigOptionElement
                }
              }
              this.genFieldTypeSelectLimit()
              if (resolveFn) {
                resolveFn()
              }
            })
      } else {
        this.genFieldTypeSelectLimit()
      }
    },
    showComponent() {
      this.projectTableFiledConfigPreSelectVisible = true;
    },
    onComponentSelect(data) {
      let selectArrJsonStr = data["showSelectOption"]
      let selectArrJson = JSON.parse(selectArrJsonStr)
      if (selectArrJson && selectArrJson.length > 0) {
        let fistOne = selectArrJson[0]
        if (fistOne.color) {
          this.projectTableFiledConfig.showAsTag = '1'
        } else {
          this.projectTableFiledConfig.showAsTag = '0'
        }
      }
      this.showSelectOptionEdit = selectArrJson || []

    },
    addShowSelectOptionEdit() {
      this.showSelectOptionEdit.push({color: 'primary'})
    },
    deleteShowSelectOptionEdit(item) {
      let arr = this.showSelectOptionEdit || []
      let deleteIndex = -1
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].value == item.value && arr[i].label == item.label) {
          deleteIndex = i
          break
        }
      }
      if (deleteIndex >= 0) {
        arr.splice(deleteIndex, 1);
      }
      this.showSelectOptionEdit = arr
    },
    handleResetSearch() {
      this.listQuery = this.$deepClone(defaultListQuery)
    },
    handleSearchList() {
      this.listQuery.current = 1
      this.getList()
    },
    handleSizeChange(val) {
      this.listQuery.current = 1
      this.listQuery.pageSize = val
      this.getList()
    },
    handleCurrentChange(val) {
      this.listQuery.current = val
      this.getList()
    },
    initDataBeforeAdd(){
      this.fromCopy = false
      this.showSelectOptionEdit = [{color: "primary"}]
      this.collectionTableFieldValue = []
      this.collectionShowTypeValue = 'vue'
      this.associationTableFieldValue = []
      this.associationTableShowField = ''
    },
    handleAdd() {
      this.initDataBeforeAdd()
      this.projectTableFiledConfig = this.$deepClone(defaultProjectTableFiledConfig)
      let currentProject = JSON.parse((localStorage.getItem('currentProject') || "{}"))
      if (currentProject && currentProject.id != null) {
        this.projectTableFiledConfig.projectId = currentProject.id;
        this.projectChangeThenInitDatasourceOption(currentProject.id)
        this.selectProjectChange(() => {
          this.addDialogVisible = true
        })
      }
    },
    handleAddByCopy(row) {
      this.handleUpdate(row)
      this.fromCopy = true
      this.editDialogVisible = false
      this.addDialogVisible = true
      delete this.projectTableFiledConfig.id
    },
    handleDelete(row) {
      this.$confirm('是否要删除该项目表字段映射配置?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        projectTableFiledConfigPostRequire('delete', {
          'id': row.id
        }).then(response => {
          if (response) {
            this.$message({
              message: response.message,
              type: response.status ? 'success' : 'error'
            })
          }
        }).finally(() => {
          this.getList()
        })
      })
    },
    handleUpdate(row) {
      this.projectTableFiledConfig = this.$deepClone(row)
      this.editDialogVisible = true
      this.selectProjectChange(() => {
        this.handleFiledNameUpdate(row.filedName)
      })
      this.showSelectOptionEdit = []
      let showSelectOptionEdit = []
      let showAsTag = !!this.projectTableFiledConfig.showTagColor
      let colorJson = {}

      if (this.projectTableFiledConfig.showSelectOption) {
        if (showAsTag) {
          colorJson = JSON.parse(this.projectTableFiledConfig.showTagColor)
        }
        const str = this.projectTableFiledConfig.showSelectOption;
        const regex = /"([^"]+)"\s*:\s*"([^"]+)"/g;
        let match;
        while ((match = regex.exec(str)) !== null) {
          const key = match[1];
          const value = match[2];
          if (showAsTag) {
            showSelectOptionEdit.push({
              value: key,
              label: value,
              color: colorJson[key]
            })
          }else{
            showSelectOptionEdit.push({
              value: key,
              label: value
            });
          }
        }
        this.showSelectOptionEdit = showSelectOptionEdit
      } else if (this.projectTableFiledConfig.associationTable) {
        let associationTableFieldValue = []
        this.associationTableShowField = ''
        let json = JSON.parse(this.projectTableFiledConfig.associationTable) || {}
        if (json.table && json.associationField) {
          associationTableFieldValue.push(json.table)
          associationTableFieldValue.push(json.associationField)
        }
        if (json.showField) {
          this.associationTableShowField = json.showField
        }
        this.associationTableFieldValue = associationTableFieldValue
      } else if (this.projectTableFiledConfig.collectionTable) {
        let collectionTableFieldValue = []
        let json = JSON.parse(this.projectTableFiledConfig.collectionTable) || {}
        if (json.table && json.associationField) {
          collectionTableFieldValue.push(json.table)
          collectionTableFieldValue.push(json.associationField)
          this.collectionShowTypeValue = json.showType
        }
        this.collectionTableFieldValue = collectionTableFieldValue
      }
    },
    processOptionBeforeUpdateAndAdd() {
      this.projectTableFiledConfig.showSelectOption = undefined;
      this.projectTableFiledConfig.showTagColor = undefined;
      let showAsTagStr = undefined
      let repeatValue = ""
      let HasNull = false
      let showAsTag = this.projectTableFiledConfig.showAsTag == "1"
      let showType = this.projectTableFiledConfig.showType;
      if (this.templateFieldTypeToTemplateFieldConfigOption[showType].fieldType == 'option') {
        showAsTagStr = this.projectTableFiledConfig.showAsTag
        let arr = this.showSelectOptionEdit || []
        if (arr.length <= 0) {
          this.$message({
            message: "选项值必填!",
            type: 'error'
          })
          return false;
        }
        let showSelectOptionJson = {}
        let showTagColorJson = {}
        arr.forEach(a => {
          if (showSelectOptionJson[a.value]) {
            repeatValue += a.value + ","
          }
          showSelectOptionJson[a.value] = a.label
          if (!a.value || !a.label) {
            HasNull = true
          }
          if (showAsTag && !a.color) {
            HasNull = true
          }
          if (showAsTag) {
            showTagColorJson[a.value] = a.color
          }
        })
        this.projectTableFiledConfig.showSelectOption = JSON.stringify(showSelectOptionJson);
        this.projectTableFiledConfig.showTagColor = JSON.stringify(showTagColorJson);
      } else if (this.templateFieldTypeToTemplateFieldConfigOption[showType].fieldType == 'switch') {
        let arr = this.showSelectOptionEdit || []
        if (arr.length !== 2) {
          this.$message({
            message: "选项值只能有两个!",
            type: 'error'
          })
          return false;
        }
        let showSelectOptionJson = {}
        let showSelectOptionStr = "{"
        let showTagColorJson = {}
        arr.forEach(a => {
          if (showSelectOptionJson[a.value]) {
            repeatValue += a.value + ","
          }
          showSelectOptionJson[a.value] = a.label
          showSelectOptionStr +=  `"${a.value}":"${a.label}",`;
          if (!a.value || !a.label) {
            HasNull = true
          }
          showTagColorJson[a.value] = a.color || ""
        })
        showSelectOptionStr = showSelectOptionStr.slice(0, -1) + '}';
        this.projectTableFiledConfig.showSelectOption = showSelectOptionStr;
        this.projectTableFiledConfig.showTagColor = JSON.stringify(showTagColorJson);
      }
      this.projectTableFiledConfig.showAsTag = showAsTagStr
      if (repeatValue) {
        this.$message({
          message: "选项值: " + repeatValue + "重复!",
          type: 'error'
        })
        return false;
      }
      if (HasNull) {
        this.$message({
          message: "选项值有空值!",
          type: 'error'
        })
        return false;
      }
      return true;
    },
    processAssociationTableBeforeUpdateAndAdd() {
      this.projectTableFiledConfig.collectionTable = undefined
      this.projectTableFiledConfig.associationTable = undefined
      let showType = this.projectTableFiledConfig.showType;
      if (showType !== 'collection' && showType !== 'association') {
        return true;
      }
      this.projectTableFiledConfig.collectionTable = undefined
      this.projectTableFiledConfig.associationTable = undefined
      if (showType === 'association') {
        let associationTableFieldValue = this.associationTableFieldValue || []
        if (associationTableFieldValue.length < 2) {
          this.$message({
            message: "关联表字段必选!",
            type: 'error'
          })
          return false;
        }
        let json = {
          table: associationTableFieldValue[0],
          associationField: associationTableFieldValue[1]
        }
        if (this.associationTableShowField) {
          json.showField = this.associationTableShowField
        }
        this.projectTableFiledConfig.associationTable = JSON.stringify(json);
        return true;
      } else if (showType === 'collection') {
        let collectionTableFieldValue = this.collectionTableFieldValue || []
        if (collectionTableFieldValue.length < 2) {
          this.$message({
            message: "关联表字段必选!",
            type: 'error'
          })
          return false;
        }
        let json = {
          table: collectionTableFieldValue[0],
          associationField: collectionTableFieldValue[1]
        }
        json.showType = this.collectionShowTypeValue
        this.projectTableFiledConfig.collectionTable = JSON.stringify(json);
        return true;
      }
    },

    handleEditDialogConfirm() {
      if (this.processOptionBeforeUpdateAndAdd() && this.processAssociationTableBeforeUpdateAndAdd()) {
        projectTableFiledConfigPostRequire('update', this.projectTableFiledConfig).then(response => {
          if (response) {
            this.$message({
              message: response.message,
              type: response.status ? 'success' : 'error'
            })
          }
          this.editDialogVisible = false
        }).finally(() => {
          this.getList()
        })
      }
    },
    handleAddDialogConfirm() {
      if (this.processOptionBeforeUpdateAndAdd() && this.processAssociationTableBeforeUpdateAndAdd()) {
        projectTableFiledConfigPostRequire('add', this.projectTableFiledConfig).then(response => {
          if (response) {
            this.$message({
              message: response.message,
              type: response.status ? 'success' : 'error'
            })
          }
          this.addDialogVisible = false
        }).finally(() => {
          this.getList()
        })
      }
    },
    getList() {
      this.listLoading = true
      projectTableFiledConfigPostRequire('listPage', this.listQuery).then(response => {
        this.listLoading = false
        this.list = response.data.records || []
        this.total = response.data.total
        if (this.fromTablePage) {
          if (this.list.length > 0) {
            this.handleUpdate(this.list[0])
            this.fromTablePage = false
          } else {
            this.initDataBeforeAdd()
            this.projectTableFiledConfig.projectId = this.listQuery.projectId
            this.projectTableFiledConfig.datasourceId = this.listQuery.datasourceId
            this.projectTableFiledConfig.tableName = this.listQuery.tableName
            this.projectTableFiledConfig.filedName = this.listQuery.filedName
            if (this.projectTableFiledConfig.projectId != null) {
              this.selectProjectChange(() => {
                this.handleFiledNameUpdate(this.listQuery.filedName)
                this.fromTablePage = false
                this.addDialogVisible = true
              })
            }
          }
        }
      })
    },
    onShowTypeChange(showType) {
      this.$forceUpdate()
      if (showType === 'switch') {
        this.showSelectOptionEdit = [
          {value: '0', label: '否'},
          {value: '1', label: '是'},
        ]
      }
    },
    projectChangeThenInitDatasourceOption(projectId) {
      if (!this.fromTablePage){
        this.listQuery.datasourceId = null
      }
      if (projectId == null) {
        projectId = this.listQuery.projectId
      }
      if (projectId == null) {
        return false;
      }

      let projectJsonElement = this.idToAllProjectJson[projectId];
      let projectDatasource = projectJsonElement.projectDatasource;
      let mutilDatasourceList = projectJsonElement.mutilDatasourceList;
      let datasourceOption = [projectDatasource]
      if (mutilDatasourceList && mutilDatasourceList.length > 0) {
        datasourceOption.push(...mutilDatasourceList)
      } else {
        this.listQuery.datasourceId = projectDatasource.id
        this.projectTableFiledConfig.datasourceId = projectDatasource.id
      }
      this.datasourceOption = datasourceOption

    },
    forceUpdateElement() {
      this.$forceUpdate()
    },
    handleFiledNameUpdate(value) {
      let arr = this.projectTableFieldOption[this.projectTableFiledConfig.tableName] || []
      for (let i = 0; i < arr.length; i++) {
        let temp = arr[i]
        if (temp.value == value) {
          let showName = temp.label || ""
          if (showName.indexOf("-") >= 0) {
            showName = showName.substring(showName.indexOf("-") + 1, showName.length);
          }
          showName = showName.trim()
          if (!this.editDialogVisible) {
            this.projectTableFiledConfig.showName = showName
          }
          // this.projectTableFiledConfig.dateType = temp.dateType
          this.projectTableFiledConfig.javaType = temp.javaType
          break
        }
      }
      this.genFieldTypeSelectLimit()
      this.forceUpdateElement()
      this.autoSelectFieldMap()

    },
    selectTableNameChange() {
      this.projectTableFiledConfig.filedName = undefined
      this.forceUpdateElement()
    },
    selectProjectChange(resolveFn) {
      this.initTableOptionByDatasourceId(
          this.projectTableFiledConfig.datasourceId,
          () => {
            this.selectTemplateChange(this.projectTableFiledConfig.projectId, () => {
              if (!this.editDialogVisible && !this.fromCopy && !this.fromTablePage) {
                this.projectTableFiledConfig.filedName = ''
                this.projectTableFiledConfig.tableName = ''
              }
              this.forceUpdateElement()
              if (resolveFn) {
                resolveFn()
              }
            })
          })
    },
    initTableOptionByDatasourceId(datasourceId, resolveFn) {
      let associationTableField = []
      this.associationTableField = []
      this.listLoading = true
      this.projectTableOption = []
      this.projectTableFieldOption = {}
      let projectTableOption = []
      let projectTableFieldOption = {}
      tablePostRequire('listAllByDatasourceId', {datasourceId: datasourceId}).then(response => {
        let tableInfos = response.data || []
        new Promise((resolve, reject) => {
          if (tableInfos.length <=0){
            resolve()
          }
          for (let i = 0; i < tableInfos.length; i++) {
            let ti = tableInfos[i]
            let label = ti.tableName + " - " + ti.tableComment
            projectTableOption.push({
              label: label,
              value: ti.tableName
            })
            let fieldNames = ti.fieldNames || []
            let tableToField = []

            let associationElement = {label: label, value: ti.tableName}
            let associationElementChildren = []
            fieldNames.forEach(fn => {
              associationElementChildren.push({label: fn.name + " - " + fn.desc, value: fn.name})
              tableToField.push({
                label: fn.name + " - " + fn.desc,
                value: fn.name,
                type: fn.type,
                javaType: fn.javaType,
                maxLength: fn.maxLength
              })
            })
            projectTableFieldOption[ti.tableName] = tableToField
            associationElement.children = associationElementChildren
            associationTableField.push(associationElement)

            if (i === (tableInfos.length - 1)) {
              this.associationTableField = associationTableField
              this.projectTableOption = projectTableOption
              this.projectTableFieldOption = projectTableFieldOption
              resolve()
            }
          }
        }).then(() => {
          if (resolveFn) {
            resolveFn()
          }
        })
      }).catch(error => {
        reject(error)
      }).finally(() => {
        this.listLoading = false
      })
    },
    autoSelectFieldMap() {
      let filedName = this.projectTableFiledConfig.filedName
      let tableName = this.projectTableFiledConfig.tableName
      let fieldTypeSelectOption = this.fieldTypeSelectOption || []
      let projectTableFieldArr = this.projectTableFieldOption[tableName] || []
      let fieldInfo = {}
      for (let i = 0; i < projectTableFieldArr.length; i++) {
        let temp = projectTableFieldArr[i]
        if (temp.value === filedName) {
          fieldInfo = temp
          break
        }
      }
      let maxLength = fieldInfo.maxLength
      if (maxLength && maxLength >= 255){
        // projectTableFiledConfig.showType =
        for (let i = 0; i < fieldTypeSelectOption.length; i++) {
          if (fieldTypeSelectOption[i].value.toString().toLowerCase().indexOf("textarea") !== -1 &&
              !fieldTypeSelectOption[i].disabled) {
            this.projectTableFiledConfig.showType = fieldTypeSelectOption[i].value
            Message.success("自动匹配字段类型【textarea】...")
            break
          }
        }
      }else if (filedName.indexOf("time") !== -1 || filedName.indexOf("date") !== -1){
        let pattern = "datetime";
        // if (filedName.indexOf("datetime") !== -1){
        //   pattern = "datetime"
        // }else if (filedName.indexOf("time") !== -1){
        //   pattern = "time"
        // }else {
        //   pattern = "date"
        // }
        for (let i = 0; i < fieldTypeSelectOption.length; i++) {
          if (fieldTypeSelectOption[i].value.toString().toLowerCase().indexOf(pattern) !== -1 &&
              !fieldTypeSelectOption[i].disabled) {
            this.projectTableFiledConfig.showType = fieldTypeSelectOption[i].value
            Message.success("自动匹配字段类型【"+fieldTypeSelectOption[i].value+"】...")
            break
          }
        }
      }

    },
  }
}
</script>
<style>
.demo-table-expand label {
  color: #99a9bf;
}

.demo-table-expand .el-form-item {
  margin-left: 10px;
  width: 100%;
}
</style>
